-
Notifications
You must be signed in to change notification settings - Fork 79
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Web support #94
Web support #94
Conversation
I'll try to keep an eye on it over the weekend |
Hello! I just tested it on Windows and it seems to work fine. It doesn't seem to work with MSVC but it worked with MinGW (GCC).
Tell me when you finish. |
I'm done on my end! |
Could you please add an option to compile the examples with all their dependencies in one file per example/app. This way the user program does not need a server. I think is the flag -sSINGLE_FILE. |
Done. |
Wow, thank you! |
This commit adds web support to minifb through emscripten. See #93
CMake build changes
The CMake build has been modified in the following way:
SrcWeb
was added. It contains the web backend (WebMiniFB.c
)UNIX
. Sections of the build targetingUNIX
had to be modified, e.g. to not add theUSE_OPENGL_API
option when building for the web.CMakeLists.txt
to their build.web_assets
is created, which copies all files fromtests/web
to the output folder. The folder contains.html
files which load the generated.js/.wasm
files, setup a canvas for rendering, and execute the test app'smain()
function. It also adds the target as a dependency to the test targets, and sets an additional linker option for each test target. The linker option specifies the module name with which the compiled minifb app can be instantiated in JavaScript.New backend features and limitations
A new backend was added in
src/web/WebMiniFB.c
. It can run all tests of minifb, including the multi-window and input tests, both in dekstop and mobile browsers.The
mfb_open_ex()
function expects that a HTMLcanvas
element with an id equal to the specifiedtitle
exists. If no such canvas exists in the DOM,mfb_open_ex()
will return an error code.Keyboard, mouse and touch input are supported. However, only a single touch will be processed, as the minifb API currently does not provide a way to deal with multi-touch. Touche events are thus interpreted as mouse events. The only supported button on the web is the left mouse button.
The web backend is using emscripten's Asyncify feature. It allows to run synchronous native code, like the minifb tests without modification. However, a minifb app on the web must still yield to the browser so DOM events can be processed. A minifb app on the web must thus periodically call
mfb_wait_sync()
, which will hand control back to the browser for a short time. This "yielding" is implemented usingrequestAnimationFrame()
, so it is vsynched and as high performance as it can be.The web backend also implements the timer api using
performance.now()
. Note that this is not a high precision timer and fudges things by 2ms to due to a Spectre mitigation. It is usually good enough for real-time apps.The web backend blits the buffer passed to
mfb_update_ex()
to the canvas associated with the window by converting the buffer to anImageData
instance, then callingContext2D.putImageData()
to draw the buffer to the canvas. The canvas' backing buffer always has the size of the buffer provided tomfb_update_ex()
. If the CSS size of the canvas is different, the browser engine will automatically up or downscale the backing buffer. To keep scaled display as pixel accurate as possible,mfb_open_ex()
will set the CSS propertyimage-rendering
topixelated
on the canvas.When blitting the user provided buffer to the canvas via
putImageData()
, the alpha channel of each pixel will be interpreted and the data will actually be blended with the current canvas backing buffer data. It is thus necessary to always set the alpha channel of pixels in the buffer passed tomfb_update_ex()
The web backend currently does not support
mfb_set_viewport()
.Test changes
The changes are using the new
MFB_ARGB
macro instead ofMFB_RGB
so each pixel receives an alpha value as well.Building for and running in the browser
To build for the web, specify the emscripten toolchain location:
The
build
folder will then contain.js
,.wasm
, and.html
files for each test, as well as aindex.html
file that links to all the test.html
files for faster navigation between tests.The tests can then be viewed in the browser by serving the contents of the
build
file via a HTTP server. E.g. using Python:Open http://localhost:8000 in the browser to check out the test apps.
Example usage
Here's a simple project that illustrates how to setup the CMake build for a project using minifb:
https://github.com/badlogic/r96/blob/main/CMakeLists.txt
I've also uploaded the minifb tests for web here: Submitted a pull request to minifb for my web backend:
https://marioslab.io/dump/minifb/